using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using FiltronASP.Helpers.HtmlTags;
using FiltronASP.Models;
using FiltronASP.Models.DAO;
using FiltronASP.Models.DAO.Interfaces;
using FiltronASP.Helpers.HttpObjects;
using System.Net;

namespace FiltronASP.Helpers.FileUpload
{
    public class UploadHelper
    {
        /// <summary>
        /// Metoda uploadujaca plik na serwer i umieszczajace odpowiednia informacje w bazie danych.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="galleryId">id galerii</param>
        /// <param name="request">obiekt zadania</param>
        /// <returns>ciag znakow spodziewany przez flasha zawierajacy rezultat uploadu</returns>
        public string DoUpload(int? pageId, int? galleryId, HttpRequestBase request)
        {
            try
            {
                if (request == null)
                {
                    return UploadConsts.NO_IMAGE_UPLOAD_RESULT_STRING;
                }   //if
                if (pageId == null)
                {
                    return UploadConsts.NO_IMAGE_UPLOAD_RESULT_STRING;
                }   //if
                if (galleryId == null)
                {
                    return UploadConsts.NO_IMAGE_UPLOAD_RESULT_STRING;
                }   //if
                foreach (string fileName in request.Files.Keys)
                {
                    if (request.Files[fileName].ContentLength > 0)
                    {
                        GalleryImage newImage = this.GetNewImage(pageId, galleryId, Path.GetExtension(request.Files[fileName].FileName));
                        if (newImage != null)
                        {
                            HttpServerUtility httpServer = HttpObjectsHelper.GetHttpServer();
                            if (httpServer != null)
                            {
                                request.Files[fileName].SaveAs(Path.Combine(httpServer.MapPath(UploadConsts.UPLOADED_IMAGE_ABSOLUTE_DIR),
                                        Path.GetFileName(newImage.gallery_image_link)));
                                this.MakeThumb(newImage.gallery_image_link);
                                return  String.Format(UploadConsts.IMAGE_UPLOAD_RESULT_STRING, newImage.gallery_image_id, newImage.gallery_image_link);
                            }   //if
                        }   //if
                    }   //if
                }   //foreach
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
            }   //catch
            return UploadConsts.NO_IMAGE_UPLOAD_RESULT_STRING;
        }

        /// <summary>
        /// Metoda umieszczajaca informacje nt. nowego obrazka w bazie.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="galleryId">id galerii</param>
        /// <param name="fileExtension">rozszerzenie pliku</param>
        /// <returns></returns>
        private GalleryImage GetNewImage(int? pageId, int? galleryId, string fileExtension)
        {
            try
            {
                if (String.IsNullOrEmpty(fileExtension))
                {
                    return null;
                }   //if
                if (pageId == null)
                {
                    return null;
                }   //if
                if (galleryId == null)
                {
                    return null;
                }   //if
                IGalleryImageDAO galleryImageDAO = new GalleryImageDAO();
                GalleryImage galleryImage = new GalleryImage();
                galleryImage.gallery_id = galleryId;
                galleryImage.page_id = pageId;
                galleryImage.gallery_image_ordering = this.GetMaxOrdering(pageId.Value, galleryId.Value) + 1;
                galleryImage.gallery_image_link = String.Empty;
                galleryImage.gallery_image_published = true;
                galleryImage.gallery_image_created = DateTime.Now;
                galleryImage.gallery_image_modified = DateTime.Now;
                galleryImage.gallery_image_info = UploadConsts.NEW_IMAGE_DEFAULT_INFO;
                galleryImage = galleryImageDAO.Add(galleryImage);
                if (galleryImage != null)
                {
                    galleryImage.gallery_image_link = this.GetNewImageLink(String.Format("{0}{1}", galleryImage.gallery_image_id, fileExtension));
                    if (galleryImageDAO.SubmitChanges())
                    {
                        return galleryImage;
                    }   //if submit
                }   //if added
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
            }   //catch
            return null;
        }

        /// <summary>
        /// Metoda pobierajaca najwyzszy porzadek dla sortowania obrazkow.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="galleryId">id galerii</param>
        /// <returns>najwyzszy porzadek dla sortowania obrazkow</returns>
        private int GetMaxOrdering(int pageId, int galleryId)
        {
            try
            {
                IGalleryImageDAO galleryImageDAO = new GalleryImageDAO();
                int? maxOrdering = galleryImageDAO.SelectMaxItemOrdering(pageId, galleryId);
                if ((maxOrdering < 0) || (maxOrdering == null))
                {
                    maxOrdering = 0;
                }   //if
                return maxOrdering.Value;
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
            }   //catch
            return 0;
        }

        /// <summary>
        /// Metoda zwracajaca linka do obrazka na podstawie jego id.
        /// </summary>
        /// <param name="galleryImageName">nazwa obrazka</param>
        /// <returns>link do obrazka</returns>
        private string GetNewImageLink(string galleryImageName)
        {
            if (String.IsNullOrEmpty(galleryImageName))
            {
                return null;
            }   //if null
            UrlHelper urlHelper = HttpObjectsHelper.GetUrlHelper();
            if (urlHelper != null)
            {
                return urlHelper.GenerateUploadedImageLink(galleryImageName);
            }   //if
            return null;
        }

        /// <summary>
        /// Tworzenie miniaturek, jak trzeba.
        /// </summary>
        /// <param name="imagePath">sciezka do obrazka</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private void MakeThumb(string imagePath)
        {
            this.MakeThumb(imagePath, 80, null);
            this.MakeThumb(imagePath, null, 80);
            this.MakeThumb(imagePath, 80, 80);
        }

        /// <summary>
        /// Tworzenie pojedynczych mianiturek.
        /// </summary>
        /// <param name="imagePath">sciezka do obrazka</param>
        /// <param name="newWidth">nowa szerokosc, gdy nullem, to skalowanie wg wysokosci</param>
        /// <param name="newHeight">nowa wysokosc, gdy nullem, to skalowanie wg szerokosci</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private void MakeThumb(string imagePath, int? newWidth, int? newHeight)
        {
            ThumbnailerHelper thumbnailerHelper = new ThumbnailerHelper();
            if (!thumbnailerHelper.MakeThumb(imagePath, newWidth, newHeight))
            {
                Logger.MyLogger.Log("UploadHelper exception: MakeThumb method failed...");
            }   //if
        }

        public static bool checkIfFileExist(string url) {
            try
            {
                HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create(url);
                request.Method = "HEAD";
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    return false;
                }
                else
                {
                    return true;
                }
               }
            catch
            {
                return false;
            }
        }

    }
}
